#ifndef TOK_H
#define TOK_H

#include "Token.h"

//#define WITH_ESCAPEMENT 0

class Tokenizer
{
	char c;                     // The current character.
	int from;                   // The index of the start of the token.
	string::const_iterator i;         // The index of the current character.
	int length;

	char q;                      // The quote character.
	string str;                  // The string value.
	int line;	

	struct IState
	{
		void Init(Tokenizer* t);
		Tokenizer* tok;
		virtual SimpleToken* Advance() = 0;
	};

	struct FinalState : public IState
	{
		virtual SimpleToken* Advance() = 0;
	};
	
	struct State : public IState
	{
		SimpleToken* Advance();
		IState* to[128];
	};

	struct Start : public State
	{
		static IState* Instance;
		SimpleToken* Advance();
		void Init(Tokenizer* t);
	};

	struct WhiteSpace : public FinalState
	{
		static IState* Instance;
		SimpleToken* Advance();
	};

	struct Name : public State
	{
		static IState* Instance;

		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		void Init(Tokenizer* t);
	};

	struct Integer : public State
	{
		static IState* Instance;
		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct Error : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		void Init(Tokenizer*);
	};

	struct Fraction : public State
	{
		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct Error : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Fraction_Exponent : public Fraction
	{
		static IState* Instance;
		struct Sign : public Fraction
		{
			static IState* Instance;
			void Init(Tokenizer*);
		};

		void Init(Tokenizer*);
	};

	struct String : public State
	{
		static IState* Instance;

		struct Error : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct Escapement : public State
		{
			static IState* Instance;
			SimpleToken* Advance();
			void Init(Tokenizer*);
		};

#ifdef WITH_ESCAPEMENT
		SimpleToken* Advance();
#endif
		void Init(Tokenizer*);
	};

	struct Char : public State
	{
		static IState* Instance;
		struct Error : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		struct Escapement : public State
		{
			static IState* Instance;
			SimpleToken* Advance();
			void Init(Tokenizer*);
		};

#ifdef WITH_ESCAPEMENT
		SimpleToken* Advance();
#endif
		void Init(Tokenizer*);
	};

	struct Operator : public State
	{
		static IState* Instance;
		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};
		
		void Init(Tokenizer*);
	};

	struct Operator_Slesh : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_PrefixEqual : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_PrefixDoubleEqual : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};


	struct Operator_Multiply : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_Plus : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_Minus : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_Less : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_More : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_And : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Operator_Or : public Operator
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};

	struct Error : public FinalState
	{
		static IState* Instance;
		SimpleToken* Advance();
	};

	struct Comment : public State
	{
		static IState* Instance;
		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		SimpleToken* Advance();
		void Init(Tokenizer*);
	};

	struct MultiLineComment : public State
	{
		static IState* Instance;
		struct End : public FinalState
		{
			static IState* Instance;
			SimpleToken* Advance();
		};

		SimpleToken* Advance();
		void Init(Tokenizer*);
	};

	
	struct MultiLineComment_PreEnd : public MultiLineComment
	{
		static IState* Instance;
		void Init(Tokenizer*);
	};


public:
	map<string, const char*> Names;
	typedef map<string, const char*>::iterator NamesIterator;

	string Code;
	
	bool Init();
	bool AtEnd()
	{
		return i == Code.end() - 1;
	}
	SimpleToken* GetToken()
	{
		return Start::Instance->Advance();
	}

};
#endif
